// const { createScopedThreejs } = require('threejs-miniprogram')
import { createScopedThreejs } from 'threejs-miniprogram'

const { renderCube } = require('../test-cases/cube')
const { renderCubes } = require('../test-cases/cubes')
const { renderSphere } = require('../test-cases/sphere')
const { renderModel } = require('../test-cases/model')

// 高德地图API Key
const AMAP_KEY = '49d0ebff5e4a0ae7dc74319f017a9f98';

const app = getApp()

Page({
  data: {
    showCamera: false,
    photoSrc: '',
    devicePosition: 'back', // 默认使用后置摄像头
    arMode: false,          // AR模式标志
    navMode: false,         // 导航模式标志
    showMap: false,         // 是否显示地图
    searchKeyword: '',      // 搜索关键词
    longitude: 116.397470,  // 默认北京天安门位置
    latitude: 39.908823,
    markers: [],            // 地图标记点
    polyline: [],           // 导航路线
    hasDestination: false,  // 是否有目的地
    destination: '',        // 目的地名称
    navDistance: '',        // 到目的地的距离
    navInstruction: '',     // 导航指示
    navSteps: [],            // 导航路径步骤
    estimatedTime: '',       // 预计到达时间
    includePoints: [],        // 包含当前位置和所有标记点的数组用于地图缩放
    // 方向指示相关
    showDirectionIndicator: false, // 是否显示方向指示器
    directionAngle: 0,             // 方向指示箭头角度
    directionText: '向前',         // 方向提示文本
    targetDirection: 0,             // 目标方向角度
    arrowColor: ''                // 箭头颜色
  },
  
  onLoad: function () {
    // 添加全局未捕获错误处理
    wx.onError((err) => {
      console.error('小程序全局错误:', err);
    });
    
    // 创建日志控制工具
    this.setupConsoleFilters();
    
    // 初始化设备方向监听状态标志
    this.deviceMotionListeningActive = false;
    
    try {
      // 初始化THREE.js
      this.initThreeJS();
      
      // 延迟一下再获取位置，确保权限请求有足够时间
      setTimeout(() => {
        // 获取用户当前位置
        this.getUserLocation();
      }, 500);
    } catch (e) {
      console.error('初始化错误:', e);
      wx.showToast({
        title: '应用初始化错误',
        icon: 'none',
        duration: 2000
      });
    }
  },
  
  // 设置控制台过滤器，避免大量无用警告
  setupConsoleFilters: function() {
    // 检查是否在开发环境
    const isDevEnv = wx.getSystemInfoSync().platform === 'devtools';
    
    // 只保留原始console对象的引用，不修改对象本身
    const originalWarn = console.warn;
    const originalLog = console.log;
    const originalInfo = console.info;
    
    // 创建过滤函数
    const shouldFilter = (args) => {
      if (!args || args.length === 0) return false;
      
      // 需要过滤的消息模式
      const filterPatterns = [
        'wxfile://',
        'interstitialAdExtInfo',
        'private_getBackgroundFetchData',
        'backgroundfetch privacy',
        'WebGL',
        'THREE.WebGLRenderer',
        'extension not supported'
      ];
      
      const msg = String(args[0]);
      return filterPatterns.some(pattern => msg.includes(pattern));
    };
    
    // 替换warn方法
    console.warn = function() {
      if (isDevEnv && !shouldFilter(arguments)) {
        originalWarn.apply(console, arguments);
      }
    };
    
    // 替换log方法
    console.log = function() {
      if (!shouldFilter(arguments)) {
        originalLog.apply(console, arguments);
      }
    };
    
    // 替换info方法
    console.info = function() {
      if (!shouldFilter(arguments)) {
        originalInfo.apply(console, arguments);
      }
    };
  },
  
  initThreeJS: function() {
    try {
      wx.createSelectorQuery()
        .select('#webgl')
        .node()
        .exec((res) => {
          try {
            if (!res || !res[0] || !res[0].node) {
              console.error('无法获取WebGL canvas节点');
              return;
            }
            
            const canvas = res[0].node
            this.canvas = canvas
            
            // 使用try-catch包装THREE.js创建，防止在不支持的设备上崩溃
            let THREE;
            try {
              THREE = createScopedThreejs(canvas);
              this.THREE = THREE;
            } catch (err) {
              console.error('THREE.js初始化失败:', err);
              wx.showToast({
                title: '3D功能初始化失败',
                icon: 'none',
                duration: 2000
              });
              return;
            }
            
            // 初始化THREE全局变量，以便后续访问
            this.scene = null;
            this.camera = null;
            this.renderer = null;
            this.cube = null;
            
            // 使用简单的立方体替代复杂模型
            this.setupCubeScene(canvas, THREE);
          } catch (err) {
            console.error('初始化WebGL上下文失败:', err);
          }
        });
    } catch (err) {
      console.error('获取canvas节点失败:', err);
      wx.showToast({
        title: '3D功能不可用',
        icon: 'none',
        duration: 2000
      });
    }
  },
  
  // 初始化AR模式下的Three.js场景
  initARThreeJS: function() {
    wx.createSelectorQuery()
      .select('#ar-webgl')
      .node()
      .exec((res) => {
        if (!res[0] || !res[0].node) {
          console.error('无法获取AR canvas节点');
          return;
        }

        const canvas = res[0].node;
        this.arCanvas = canvas;
        const THREE = createScopedThreejs(canvas);
        this.arTHREE = THREE;
        
        // 初始化AR场景相关变量
        this.arScene = null;
        this.arCamera = null;
        this.arRenderer = null;
        this.arModel = null;
        
        // 设置AR场景
        this.setupARScene(canvas, THREE);
      });
  },
  
  setupCubeScene: function(canvas, THREE) {
    try {
      // 设置合适的canvas尺寸
      const info = wx.getSystemInfoSync();
      const width = info.windowWidth;
      const height = Math.floor(width * 0.75);  // 使用固定宽高比例，避免奇怪尺寸导致问题
      
      // 设置canvas大小
      canvas.width = width;
      canvas.height = height;
      
      // 创建场景
      const scene = new THREE.Scene();
      scene.background = new THREE.Color(0xf0f0f0);  // 设置浅灰色背景，提高兼容性
      this.scene = scene;
      
      // 创建相机
      const camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 100);
      camera.position.z = 5;
      this.camera = camera;
      
      // 检查WebGL支持
      let renderer;
      try {
        // 创建渲染器并添加错误捕获
        const contextAttributes = {
          alpha: true,
          antialias: false,  // 关闭抗锯齿以提高性能
          powerPreference: 'default',
          preserveDrawingBuffer: false,
          depth: true,
          stencil: false,
          failIfMajorPerformanceCaveat: false
        };
        
        renderer = new THREE.WebGLRenderer({ 
          canvas: canvas,
          precision: 'mediump',  // 使用中等精度，提高兼容性
          ...contextAttributes
        });
      } catch (e) {
        console.error('WebGL渲染器创建失败:', e);
        return;
      }
      
      // 检查渲染器是否成功创建
      if (!renderer) {
        console.warn('WebGL渲染器创建失败，可能不支持WebGL');
        return;
      }
      
      renderer.setSize(width, height, false);  // 第三个参数false避免修改canvas样式
      renderer.setPixelRatio(1);  // 使用固定像素比例，避免高DPI设备性能问题
      renderer.setClearColor(0xf0f0f0, 1);  // 设置清除颜色
      
      try {
        // 禁用不必要的WebGL扩展和功能，提高兼容性
        renderer.getContext().getExtension('WEBGL_debug_renderer_info');
      } catch (e) {
        // 忽略此错误，有些设备不支持这个扩展
      }
      
      this.renderer = renderer;
      
      // 创建立方体 - 使用基础材质避免需要高级WebGL功能
      const geometry = new THREE.BoxGeometry(1.5, 1.5, 1.5);
      const material = new THREE.MeshBasicMaterial({ color: 0x44aa88 });
      const cube = new THREE.Mesh(geometry, material);
      this.cube = cube;
      scene.add(cube);
      
      // 添加灯光 - 只使用环境光，最简单最兼容
      const light = new THREE.AmbientLight(0xffffff, 1.0);
      scene.add(light);
      
      // 渲染循环
      const animate = () => {
        if (this.data.arMode) return; // AR模式下不渲染普通场景
        
        // 使用try-catch避免渲染错误导致整个应用崩溃
        try {
          const animationId = canvas.requestAnimationFrame(animate);
          this.animationId = animationId; // 保存动画ID，便于取消
          
          if (cube) {
            cube.rotation.x += 0.01;
            cube.rotation.y += 0.01;
          }
          
          if (renderer && scene && camera) {
            renderer.render(scene, camera);
          }
        } catch (e) {
          console.error('渲染循环发生错误:', e);
          // 发生错误时尝试取消动画，避免持续错误
          if (this.animationId) {
            try {
              canvas.cancelAnimationFrame(this.animationId);
            } catch (err) {
              // 忽略取消动画时的错误
            }
          }
        }
      };
      
      animate();
    } catch(e) {
      console.error('3D场景初始化错误:', e);
    }
  },
  
  // 设置AR场景
  setupARScene: function(canvas, THREE) {
    // 获取设备信息以适配尺寸
    const info = wx.getSystemInfoSync();
    const width = info.windowWidth;
    const height = info.windowHeight;
    
    // 设置canvas大小
    canvas.width = width;
    canvas.height = height;
    
    // 创建AR场景
    const scene = new THREE.Scene();
    this.arScene = scene;
    
    // 创建相机 - 使用透视相机模拟AR效果
    const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
    camera.position.z = 5;
    this.arCamera = camera;
    
    // 创建透明背景的渲染器
    const renderer = new THREE.WebGLRenderer({ 
      canvas: canvas,
      alpha: true,  // 透明背景
      antialias: true
    });
    renderer.setSize(width, height);
    renderer.setClearColor(0x000000, 0); // 透明背景
    this.arRenderer = renderer;
    
    // 创建AR中显示的3D模型 (先用立方体代替)
    const geometry = new THREE.BoxGeometry(1, 1, 1);
    const material = new THREE.MeshPhongMaterial({ 
      color: 0x00ff00,
      transparent: true,
      opacity: 0.8
    });
    
    const cube = new THREE.Mesh(geometry, material);
    cube.position.set(0, 0, -3); // 放在相机前方
    this.arModel = cube;
    scene.add(cube);
    
    // 添加灯光
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    scene.add(ambientLight);
    
    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
    directionalLight.position.set(0, 10, 5);
    scene.add(directionalLight);
    
    // AR渲染循环
    const arAnimate = () => {
      if (!this.data.arMode) return; // 非AR模式下不渲染AR场景
      
      canvas.requestAnimationFrame(arAnimate);
      
      if (this.arModel) {
        this.arModel.rotation.x += 0.01;
        this.arModel.rotation.y += 0.01;
      }
      
      renderer.render(scene, camera);
    };
    
    arAnimate();
  },
  
  // 进入AR模式
  enterARMode: function() {
    // 请求相机权限
    wx.authorize({
      scope: 'scope.camera',
      success: () => {
        this.setData({
          arMode: true,
          showCamera: false,
          photoSrc: ''
        }, () => {
          // 初始化AR模式的Three.js场景
          setTimeout(() => {
            this.initARThreeJS();
          }, 300); // 延迟确保DOM已更新
        });
      },
      fail: (err) => {
        console.error('AR模式需要相机权限:', err);
        wx.showToast({
          title: 'AR模式需要相机权限',
          icon: 'none'
        });
      }
    });
  },
  
  // 退出AR模式
  exitARMode: function() {
    this.setData({
      arMode: false
    });
  },
  
  // 重置AR模型位置
  resetModelPosition: function() {
    if (this.arModel) {
      this.arModel.position.set(0, 0, -3);
      this.arModel.rotation.set(0, 0, 0);
    }
  },
  
  // 摄像头相关函数
  openCamera: function() {
    // 打开摄像头前先请求授权
    wx.authorize({
      scope: 'scope.camera',
      success: () => {
        this.setData({
          showCamera: true,
          photoSrc: ''
        });
      },
      fail: (err) => {
        wx.showToast({
          title: '请授权使用摄像头',
          icon: 'none'
        });
      }
    });
  },
  
  closeCamera: function() {
    this.setData({
      showCamera: false
    });
  },
  
  switchCamera: function() {
    this.setData({
      devicePosition: this.data.devicePosition === 'back' ? 'front' : 'back'
    });
  },
  
  cameraError: function(e) {
    console.error('相机错误:', e.detail);
    wx.showToast({
      title: '相机出错',
      icon: 'none'
    });
  },
  
  takePhoto: function() {
    const cameraContext = wx.createCameraContext();
    
    cameraContext.takePhoto({
      quality: 'high',
      success: (res) => {
        this.setData({
          photoSrc: res.tempImagePath,
          showCamera: false
        });
      },
      fail: (err) => {
        console.error('拍照失败:', err);
        wx.showToast({
          title: '拍照失败',
          icon: 'none'
        });
      }
    });
  },
  
  retakePhoto: function() {
    this.setData({
      photoSrc: '',
      showCamera: true
    });
  },
  
  applyPhotoTexture: function() {
    const THREE = this.THREE;
    if (!THREE || !this.cube || !this.data.photoSrc) {
      return;
    }
    
    // 创建图片纹理
    const textureLoader = new THREE.TextureLoader();
    
    textureLoader.load(this.data.photoSrc, (texture) => {
      // 应用纹理到立方体的材质
      const material = new THREE.MeshBasicMaterial({ map: texture });
      this.cube.material = material;
      
      // 如果AR模型存在，也应用相同纹理
      if (this.arModel) {
        this.arModel.material = new THREE.MeshPhongMaterial({ 
          map: texture,
          transparent: true,
          opacity: 0.9
        });
      }
      
      // 显示成功提示
      wx.showToast({
        title: '纹理应用成功',
        icon: 'success'
      });
    }, 
    undefined, 
    (err) => {
      console.error('纹理加载失败:', err);
      wx.showToast({
        title: '纹理加载失败',
        icon: 'none'
      });
    });
  },
  
  // 触摸事件处理
  touchStart(e) {
    if (this.data.arMode && this.arCanvas) {
      this.arCanvas.dispatchTouchEvent({...e, type:'touchstart'});
      
      // 记录触摸开始位置，用于AR模型移动
      this.touchStartX = e.touches[0].x;
      this.touchStartY = e.touches[0].y;
    } else if (this.canvas) {
      this.canvas.dispatchTouchEvent({...e, type:'touchstart'});
    }
  },
  
  touchMove(e) {
    if (this.data.arMode && this.arCanvas) {
      this.arCanvas.dispatchTouchEvent({...e, type:'touchmove'});
      
      // AR模式下移动模型
      if (this.arModel && e.touches.length === 1) {
        const deltaX = (e.touches[0].x - this.touchStartX) * 0.01;
        const deltaY = (e.touches[0].y - this.touchStartY) * -0.01; // 反转Y轴
        
        this.arModel.position.x += deltaX;
        this.arModel.position.y += deltaY;
        
        this.touchStartX = e.touches[0].x;
        this.touchStartY = e.touches[0].y;
      }
    } else if (this.canvas) {
      this.canvas.dispatchTouchEvent({...e, type:'touchmove'});
    }
  },
  
  touchEnd(e) {
    if (this.data.arMode && this.arCanvas) {
      this.arCanvas.dispatchTouchEvent({...e, type:'touchend'});
    } else if (this.canvas) {
      this.canvas.dispatchTouchEvent({...e, type:'touchend'});
    }
  },
  
  // 获取用户位置
  getUserLocation: function() {
    wx.showLoading({
      title: '获取位置中...',
    });
    
    // 首先检查是否有位置权限
    wx.getSetting({
      success: (res) => {
        if (!res.authSetting['scope.userLocation']) {
          // 如果没有权限，主动向用户请求
          wx.authorize({
            scope: 'scope.userLocation',
            success: () => {
              // 权限获取成功后获取位置
              this.getLocationInfo();
            },
            fail: (err) => {
              wx.hideLoading();
              console.error('位置权限请求被拒绝:', err);
              wx.showModal({
                title: '位置权限提示',
                content: '为了实现导航功能，需要获取您的位置权限。请在设置中允许访问位置信息。',
                showCancel: false
              });
            }
          });
        } else {
          // 已有权限，直接获取位置
          this.getLocationInfo();
        }
      },
      fail: (err) => {
        wx.hideLoading();
        console.error('获取设置失败:', err);
        wx.showToast({
          title: '获取设置失败',
          icon: 'none',
          duration: 2000
        });
      }
    });
  },
  
  // 获取位置信息
  getLocationInfo: function() {
    // 首先获取单次位置
    wx.getLocation({
      type: 'gcj02',
      success: (res) => {
        wx.hideLoading();
        const { latitude, longitude } = res;
        console.log('当前位置:', latitude, longitude);
        
        // 开始连续获取位置更新
        this.startLocationUpdate();
        
        // 设置初始位置
        this.setData({
          latitude,
          longitude,
          markers: [{
            id: 999, // 用户位置标记id
            latitude,
            longitude,
            iconPath: '',
            width: 32,
            height: 32,
            anchor: {
              x: 0.5,
              y: 0.5
            },
            callout: {
              content: '我的位置',
              color: '#000000',
              fontSize: 12,
              borderRadius: 5,
              borderWidth: 1,
              borderColor: '#cccccc',
              bgColor: '#ffffff',
              padding: 5,
              display: 'BYCLICK',
              textAlign: 'center'
            }
          }],
          includePoints: [{
            latitude: latitude,
            longitude: longitude
          }]
        });
      },
      fail: (err) => {
        wx.hideLoading();
        console.error('获取位置失败:', err);
        wx.showModal({
          title: '获取位置失败',
          content: '请确保允许小程序使用位置权限，并开启设备的GPS定位功能。',
          showCancel: false
        });
      }
    });
  },
  
  // 打开地图
  openMap: function() {
    this.getUserLocation(); // 刷新位置
    this.setData({
      showMap: true,
      showCamera: false,
      photoSrc: ''
    });
  },
  
  // 关闭地图
  closeMap: function() {
    this.setData({
      showMap: false
    });
  },
  
  // 处理搜索输入
  onSearchInput: function(e) {
    this.setData({
      searchKeyword: e.detail.value
    });
  },
  
  // 搜索位置
  searchLocation: function() {
    if (!this.data.searchKeyword) {
      wx.showToast({
        title: '请输入搜索关键词',
        icon: 'none'
      });
      return;
    }
    
    wx.showLoading({
      title: '搜索中...',
    });
    
    // 获取当前位置信息以限制搜索范围
    const currentLng = this.data.longitude;
    const currentLat = this.data.latitude;
    
    // 使用当前坐标的经纬度范围构建边界，限制搜索范围
    // 大约限制在当前位置周围20公里范围内
    const regionNorthEast = `${currentLat + 0.18},${currentLng + 0.18}`;  // 右上角
    const regionSouthWest = `${currentLat - 0.18},${currentLng - 0.18}`;  // 左下角
    
    // 调用高德地图搜索API，带有强制按区域搜索的参数
    wx.request({
      url: 'https://restapi.amap.com/v3/place/text',
      data: {
        key: AMAP_KEY,
        keywords: this.data.searchKeyword,
        city: '', // 不指定城市，使用区域搜索
        output: 'json',
        location: `${currentLng},${currentLat}`,
        radius: 20000,  // 20公里以内
        sortrule: 'distance', // 按距离排序
        extensions: 'all',    // 返回详细信息
        offset: 25,  // 增加返回POI个数
        page: 1,
        // 强制使用区域搜索，确保只返回当前位置附近的结果
        polygon: `${regionSouthWest}|${regionNorthEast.split(',')[0]},${regionSouthWest.split(',')[1]}|${regionNorthEast}|${regionSouthWest.split(',')[0]},${regionNorthEast.split(',')[1]}`
      },
      success: (res) => {
        wx.hideLoading();
        
        if (res.data && res.data.pois && res.data.pois.length > 0) {
          console.log('搜索结果:', res.data.pois);
          
          // 计算所有POI的距离，并按距离排序
          let searchResults = res.data.pois.map(poi => {
            const [lng, lat] = poi.location.split(',');
            const distance = this.calculateDistance(
              currentLat, currentLng,
              parseFloat(lat), parseFloat(lng)
            );
            
            return {
              ...poi,
              calculatedDistance: distance
            };
          }).sort((a, b) => a.calculatedDistance - b.calculatedDistance);
          
          // 限制最多显示5个结果
          const poiList = searchResults.slice(0, 5);
          
          // 显示确认对话框
          if (poiList.length > 1) {
            let items = poiList.map(poi => {
              const distance = poi.calculatedDistance / 1000; // 转换为公里
              const location = poi.cityname ? `${poi.cityname} ${poi.adname || ''}` : (poi.adname || '');
              return `${poi.name} (${location}, ${distance.toFixed(1)}公里)`;
            });
            
            wx.showActionSheet({
              itemList: items,
              success: (res) => {
                if (res.tapIndex !== undefined) {
                  const selectedPoi = poiList[res.tapIndex];
                  this.processPoi(selectedPoi);
                }
              }
            });
          } else if (poiList.length === 1) {
            this.processPoi(poiList[0]);
          }
        } else {
          console.error('未找到相关位置:', res.data);
          wx.showToast({
            title: '未找到相关位置',
            icon: 'none'
          });
        }
      },
      fail: (err) => {
        wx.hideLoading();
        console.error('搜索位置失败：', err);
        wx.showToast({
          title: '搜索位置失败',
          icon: 'none'
        });
      }
    });
  },
  
  // 处理POI结果
  processPoi: function(poi) {
    if (!poi || !poi.location) return;
    
    const [lng, lat] = poi.location.split(',');
    const marker = {
      id: 0,
      latitude: parseFloat(lat),
      longitude: parseFloat(lng),
      title: poi.name,
      width: 20,
      height: 30,
      callout: {
        content: poi.name,
        color: '#000000',
        fontSize: 12,
        borderRadius: 5,
        bgColor: '#ffffff',
        padding: 5,
        display: 'ALWAYS'
      },
      address: poi.address,
      distance: poi.distance
    };
    
    // 添加用户当前位置标记
    const markers = [
      // 用户位置标记
      {
        id: 999, // 用户位置标记id
        latitude: this.data.latitude,
        longitude: this.data.longitude,
        iconPath: '',
        width: 32,
        height: 32,
        anchor: {
          x: 0.5,
          y: 0.5
        },
        callout: {
          content: '我的位置',
          color: '#000000',
          fontSize: 12,
          borderRadius: 5,
          borderWidth: 1,
          borderColor: '#cccccc',
          bgColor: '#ffffff',
          padding: 5,
          display: 'BYCLICK',
          textAlign: 'center'
        }
      },
      // 目的地标记
      marker
    ];
    
    this.setData({
      markers: markers,
      includePoints: [
        {
          latitude: this.data.latitude,
          longitude: this.data.longitude
        },
        {
          latitude: parseFloat(lat),
          longitude: parseFloat(lng)
        }
      ]
    });
    
    // 选择目的地
    this.selectDestination(marker);
    
    // 缩放地图以显示所有标记点
    const mapContext = wx.createMapContext('map');
    mapContext.includePoints({
      points: [
        {
          latitude: this.data.latitude,
          longitude: this.data.longitude
        },
        {
          latitude: parseFloat(lat),
          longitude: parseFloat(lng)
        }
      ],
      padding: [80, 80, 80, 80]
    });
  },
  
  // 点击地图标记
  markerTap: function(e) {
    const markerId = e.markerId;
    const marker = this.data.markers.find(item => item.id === markerId);
    if (marker) {
      this.selectDestination(marker);
    }
  },
  
  // 选择目的地
  selectDestination: function(marker) {
    const destinationInfo = marker.title + (marker.address ? ` (${marker.address})` : '');
    
    this.setData({
      destination: destinationInfo,
      hasDestination: true
    });
    
    console.log('已选择目的地:', destinationInfo);
    
    // 获取导航路径
    this.getNavigationPath(this.data.latitude, this.data.longitude, marker.latitude, marker.longitude);
  },
  
  // 获取导航路径
  getNavigationPath: function(fromLat, fromLng, toLat, toLng) {
    wx.showLoading({
      title: '获取路线中...',
    });
    
    // 检查参数是否有效
    if (!fromLat || !fromLng || !toLat || !toLng) {
      console.error('导航参数无效:', fromLat, fromLng, toLat, toLng);
      wx.hideLoading();
      wx.showToast({ title: '导航参数无效', icon: 'none' });
      return;
    }
    
    console.log(`获取从 (${fromLat},${fromLng}) 到 (${toLat},${toLng}) 的导航路径`);
    
    // 调用高德地图API获取路径规划
    wx.request({
      url: 'https://restapi.amap.com/v3/direction/walking',
      data: {
        key: AMAP_KEY,
        origin: `${fromLng},${fromLat}`,
        destination: `${toLng},${toLat}`,
        output: 'json'
      },
      success: (res) => {
        wx.hideLoading();
        
        console.log('高德导航API返回数据:', res.data);
        
        if (res.data && res.data.status === '1' && res.data.route && res.data.route.paths && res.data.route.paths.length > 0) {
          const path = res.data.route.paths[0];
          const steps = path.steps || [];
          
          if (steps.length === 0) {
            console.error('未返回路径步骤数据');
            wx.showToast({ title: '未能获取到路径信息', icon: 'none' });
            return;
          }
          
          // 提取所有步骤的路径点
          let allPoints = [];
          this.navSteps = steps.map((step, index) => {
            // 解析每个步骤的折线坐标
            const polylinePoints = this.decodePolyline(step.polyline);
            allPoints = allPoints.concat(polylinePoints);
            
            return {
              index: index,
              instruction: step.instruction || '请沿路线前进',
              distance: parseInt(step.distance || '0', 10),
              polyline: polylinePoints,
              orientation: step.orientation || '',
              road_name: step.road_name || ''
            };
          });
          
          // 确认路径点有效性
          if (!allPoints || allPoints.length < 2) {
            console.error('路径坐标点无效或不足');
            wx.showToast({ title: '路径数据不完整', icon: 'none' });
            return;
          }
          
          // 设置路径数据
          const polyline = [{
            points: allPoints,
            color: '#4285f4',
            width: 6,
            arrowLine: true,
            borderColor: '#72a8ff',
            borderWidth: 1
          }];
          
          // 获取路径总距离
          const distance = path.distance || '0';
          
          // 更新UI
          this.setData({
            polyline: polyline,
            navDistance: distance,
            includePoints: [
              { latitude: fromLat, longitude: fromLng },
              { latitude: toLat, longitude: toLng }
            ].concat(points.slice(1, -1).filter((pt, idx) => idx % 5 === 0))
          });
          
          // 在导航模式下，更新导航场景
          if (this.data.navMode) {
            // 计算初始导航指南针方向
            const firstStep = points.length > 1 ? points[1] : null;
            if (firstStep) {
              const dx = firstStep.longitude - fromLng;
              const dy = firstStep.latitude - fromLat;
              
              // 计算方位角（0度为北，顺时针增加）
              let bearing = Math.atan2(dx, dy) * 180 / Math.PI;
              if (bearing < 0) bearing += 360;
              
              this.targetDirection = bearing;
              console.log('初始导航方向设置为:', bearing.toFixed(2), '度');
            }
          }
        } else {
          console.error('获取导航路径失败:', res.data);
          wx.showToast({
            title: '获取导航路径失败',
            icon: 'none'
          });
        }
      },
      fail: (err) => {
        wx.hideLoading();
        console.error('请求导航路径失败：', err);
        wx.showToast({
          title: '请求导航路径失败',
          icon: 'none'
        });
      }
    });
  },
  
  // 解码折线坐标
  decodePolyline: function(polyline) {
    if (!polyline) {
      console.warn('折线坐标为空');
      return [];
    }
    
    try {
      const points = [];
      const lines = polyline.split(';');
      
      lines.forEach(point => {
        if (!point || point.indexOf(',') === -1) {
          return; // 跳过无效坐标点
        }
        
        const [lng, lat] = point.split(',');
        const longitude = parseFloat(lng);
        const latitude = parseFloat(lat);
        
        // 验证坐标有效性
        if (!isNaN(longitude) && !isNaN(latitude) && 
            longitude >= -180 && longitude <= 180 && 
            latitude >= -90 && latitude <= 90) {
          points.push({
            longitude: longitude,
            latitude: latitude
          });
        } else {
          console.warn('忽略无效坐标点:', point);
        }
      });
      
      return points;
    } catch (error) {
      console.error('解析折线坐标失败:', error, polyline);
      return [];
    }
  },
  
  // 开始导航
  startNavigation: function() {
    if (!this.data.hasDestination) {
      wx.showToast({
        title: '请先选择目的地',
        icon: 'none'
      });
      return;
    }
    
    wx.showModal({
      title: '开始导航',
      content: `是否开始前往${this.data.destination}的AR导航？`,
      success: (res) => {
        if (res.confirm) {
          // 重置导航相关状态变量
          this.mapUpdateCount = 0;
          this.lastMapUpdate = 0;
          this.lastNavUpdate = 0;
          this.targetDirection = 0;  // 初始化目标方向
          this.lastReportedAngle = undefined; // 重置平滑角度
          this.motionUpdateCount = 0; // 初始化运动更新计数器
          
          // 更新UI状态
          this.setData({
            navMode: true,
            arMode: false,
            showMap: false,
            showDirectionIndicator: false,  // 初始不显示方向指示器
            directionAngle: 0,
            directionText: '正在计算方向...',
            arrowColor: '#4285f4',  // 设置默认箭头颜色
            // 确保地图中心是用户当前位置
            latitude: this.data.latitude,
            longitude: this.data.longitude
          }, () => {
            // 初始化导航AR场景
            setTimeout(() => {
              this.initNavARScene();
              
              // 监听方向指示器状态变化
              this.watchDirectionIndicator();
              
              // 开始位置更新
              this.startLocationUpdate();
            }, 300);
          });
        }
      }
    });
  },
  
  // 监听方向指示器状态变化
  watchDirectionIndicator: function() {
    // 使用setData的回调来确保在UI更新后执行相应的操作
    this.oldSetData = this.setData;
    
    // 重写setData方法以便监听方向指示器状态变化
    this.setData = (data, callback) => {
      // 调用原始setData方法
      this.oldSetData(data, () => {
        // 检查是否有指示器状态变化
        if ('showDirectionIndicator' in data) {
          // 确保小箭头和指示器状态同步
          if (this.navArrow) {
            console.log(`AR箭头可见性设置为: ${!data.showDirectionIndicator}`);
            
            // 为了避免小箭头和方向指示器同时出现
            // 当方向指示器显示时，隐藏小箭头；反之亦然
            this.navArrow.visible = !data.showDirectionIndicator;
          }
        }
        
        // 执行原始回调
        if (typeof callback === 'function') {
          callback();
        }
      });
    };
  },
  
  // 停止导航
  stopNavigation: function() {
    // 先复制标志位，然后再改变状态
    const wasNavActive = this.data.navMode;
    
    // 立即更新UI状态
    this.setData({
      navMode: false,
      showDirectionIndicator: false // 确保方向指示器被隐藏
    });
    
    // 如果导航模式本来就是关闭的，就不执行后续操作
    if (!wasNavActive) {
      console.log('导航模式已经停止，无需再次停止');
      return;
    }
    
    // 恢复原始的setData方法
    if (this.oldSetData) {
      this.setData = this.oldSetData;
      this.oldSetData = null;
    }
    
    // 停止位置更新
    this.stopLocationUpdate();
    
    // 停止设备方向监听
    this.stopDeviceOrientation();
    
    // 清除方向相关状态
    this.targetDirection = undefined;
    this.lastReportedAngle = undefined;
    this.motionUpdateCount = 0;
    
    console.log('导航模式已停止，所有资源已清理');
  },
  
  // 重置导航方向
  recenterNavigation: function() {
    if (this.navArrow) {
      this.navArrow.rotation.y = 0;
    }
    
    // 重置方向指示器
    this.setData({
      showDirectionIndicator: false
    });
    
    // 重置平滑角度记录
    this.lastReportedAngle = undefined;
    this.motionUpdateCount = 0;
    
    // 手动触发一次导航更新
    if (this.data.latitude && this.data.longitude) {
      this.updateNavigation(this.data.longitude, this.data.latitude);
    }
    
    wx.showToast({
      title: '方向已重置',
      icon: 'success'
    });
  },
  
  // 开始位置更新
  startLocationUpdate: function() {
    // 开始监听位置变化
    wx.startLocationUpdate({
      success: (res) => {
        console.log('开始位置更新成功');
        
        // 监听位置变化
        wx.onLocationChange((res) => {
          const { latitude, longitude } = res;
          console.log('位置已更新:', latitude, longitude);
          
          // 更新位置数据
          this.updateCurrentLocation(latitude, longitude);
          
          // 如果在导航模式，则更新导航
          if (this.data.navMode) {
            this.updateNavigation(longitude, latitude);
          }
        });
      },
      fail: (err) => {
        console.error('开始位置更新失败:', err);
        
        // 根据错误代码提供更具体的提示
        let errorMsg = '位置更新失败，请检查权限和网络';
        
        if (err.errMsg && err.errMsg.indexOf('permission') > -1) {
          errorMsg = '位置权限不足，请在设置中允许"使用我的位置"和"后台定位"。';
        }
        
        wx.showModal({
          title: '位置更新失败',
          content: errorMsg,
          showCancel: false
        });
      }
    });
  },
  
  // 停止位置更新
  stopLocationUpdate: function() {
    wx.stopLocationUpdate({
      success: (res) => {
        console.log('停止位置更新成功');
        wx.offLocationChange(); // 取消位置变化监听
      }
    });
  },
  
  // 更新当前位置和地图
  updateCurrentLocation: function(latitude, longitude) {
    // 如果位置变化较小，不更新地图中心点以减少抖动
    const lastLat = this.data.latitude || latitude;
    const lastLng = this.data.longitude || longitude;
    
    // 计算位置变化距离(米)
    const distanceMoved = this.calculateDistance(lastLat, lastLng, latitude, longitude);
    
    // 只有当移动超过1米或没有设置过位置时，才更新位置
    const shouldUpdateLocation = distanceMoved > 1.0 || !this.data.latitude || !this.data.longitude;
    
    // 构建新的数据对象
    const newData = {};
    
    // 只有当位置变化足够大时才更新位置数据
    if (shouldUpdateLocation) {
      newData.latitude = latitude;
      newData.longitude = longitude;
    }
    
    // 如果有需要更新的数据，则更新
    if (Object.keys(newData).length > 0) {
      this.setData(newData);
    }
  },
  
  // 更新导航信息
  updateNavigation: function(lng, lat) {
    // 限制更新频率，降至每1.5秒最多更新一次，减少方向变化频率
    const now = Date.now();
    if (this.lastNavUpdate && now - this.lastNavUpdate < 1500) {
      return; // 限制每1.5秒最多更新一次
    }
    this.lastNavUpdate = now;
    
    // 如果有导航步骤，计算距离并更新指令
    if (this.navSteps && this.navSteps.length > 0) {
      let minDistance = Infinity;
      let currentStep = null;
      let currentStepIndex = 0;
      
      // 找到最近的步骤
      this.navSteps.forEach((step, index) => {
        step.polyline.forEach(point => {
          const distance = this.calculateDistance(
            lat, lng,
            point.latitude, point.longitude
          );
          
          if (distance < minDistance) {
            minDistance = distance;
            currentStep = step;
            currentStepIndex = index;
          }
        });
      });
      
      // 计算到目的地的总距离
      let remainingDistance = 0;
      for (let i = currentStepIndex; i < this.navSteps.length; i++) {
        remainingDistance += this.navSteps[i].distance;
      }
      
      // 计算预计到达时间（假设步行速度为4km/h）
      const walkingSpeedMPS = 1.1; // 米/秒
      const estimatedTimeMinutes = Math.ceil(remainingDistance / walkingSpeedMPS / 60);
      
      // 只有当信息变化较大时才更新导航信息，减少不必要的UI更新
      // 距离变化超过5米，或时间变化超过1分钟，或指令改变
      if (Math.abs(this.data.navDistance - remainingDistance) > 5 || 
          this.data.estimatedTime !== estimatedTimeMinutes ||
          (currentStep && this.data.navInstruction !== currentStep.instruction)) {
        
        this.setData({
          navDistance: remainingDistance,
          navInstruction: currentStep ? currentStep.instruction : '正在计算...',
          estimatedTime: estimatedTimeMinutes
        });
      }
      
      // 更新AR场景中的箭头方向
      if (this.navArrow) {
        this.updateNavArrowDirection(currentStep);
      }
    }
  },
  
  // 计算两点之间的距离（米）
  calculateDistance: function(lat1, lon1, lat2, lon2) {
    const R = 6371000; // 地球半径，单位：米
    const dLat = this.deg2rad(lat2 - lat1);
    const dLon = this.deg2rad(lon2 - lon1);
    const a = 
      Math.sin(dLat/2) * Math.sin(dLat/2) +
      Math.cos(this.deg2rad(lat1)) * Math.cos(this.deg2rad(lat2)) * 
      Math.sin(dLon/2) * Math.sin(dLon/2);
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    return R * c;
  },
  
  // 角度转弧度
  deg2rad: function(deg) {
    return deg * (Math.PI/180);
  },
  
  // 初始化导航AR场景
  initNavARScene: function() {
    wx.createSelectorQuery()
      .select('#nav-webgl')
      .node()
      .exec((res) => {
        if (!res[0] || !res[0].node) {
          console.error('无法获取导航AR canvas节点');
          return;
        }

        const canvas = res[0].node;
        this.navCanvas = canvas;
        const THREE = createScopedThreejs(canvas);
        this.navTHREE = THREE;
        
        // 设置AR导航场景
        this.setupNavARScene(canvas, THREE);
      });
  },
  
  // 设置导航AR场景
  setupNavARScene: function(canvas, THREE) {
    try {
      // 获取设备信息以适配尺寸
      const info = wx.getSystemInfoSync();
      const width = info.windowWidth;
      const height = info.windowHeight;
      
      // 设置canvas大小
      canvas.width = width;
      canvas.height = height;
      
      // 保存THREE引用供其他函数使用
      this.THREE = THREE;
      
      // 创建导航AR场景
      const scene = new THREE.Scene();
      this.navScene = scene;
      
      // 创建相机 - 使用更大的视野角度
      const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
      camera.position.y = 1.6; // 模拟人眼高度
      camera.rotation.x = -Math.PI / 6; // 更大的向下倾斜角度
      this.navCamera = camera;
      
      // 安全创建渲染器
      let renderer;
      try {
        renderer = new THREE.WebGLRenderer({ 
          canvas: canvas,
          alpha: true,
          antialias: true,
          precision: 'mediump', // 中等精度提高兼容性
          powerPreference: 'default'
        });
      } catch (e) {
        console.error('AR导航渲染器创建失败:', e);
        wx.showToast({
          title: 'AR功能不受支持',
          icon: 'none',
          duration: 2000
        });
        // 退出导航模式
        setTimeout(() => {
          this.stopNavigation();
        }, 2000);
        return;
      }
      
      if (!renderer) {
        console.error('AR导航渲染器为空');
        this.stopNavigation();
        return;
      }
      
      renderer.setSize(width, height);
      renderer.setClearColor(0x000000, 0);
      // 设置像素比例为1以提高性能
      renderer.setPixelRatio(1);
      this.navRenderer = renderer;
      
      // 创建导航箭头和指示器
      this.createNavArrow(THREE, scene);
      
      // 添加环境光
      const ambientLight = new THREE.AmbientLight(0xffffff, 1);
      scene.add(ambientLight);
      
      // 渲染循环
      const navAnimate = () => {
        if (!this.data.navMode) return;
        
        try {
          canvas.requestAnimationFrame(navAnimate);
          renderer.render(scene, camera);
        } catch (e) {
          console.error('AR导航渲染错误:', e);
        }
      };
      
      navAnimate();
      
      // 开始监听设备方向
      this.startDeviceOrientation();
    } catch (e) {
      console.error('AR导航场景初始化错误:', e);
      wx.showToast({
        title: 'AR导航初始化失败',
        icon: 'none',
        duration: 2000
      });
      this.stopNavigation();
    }
  },
  
  // 创建导航箭头和指示器
  createNavArrow: function(THREE, scene) {
    const arrowGroup = new THREE.Group();
    
    // 创建一个双层V形箭头
    const createVShape = (color, size, yOffset) => {
      const shape = new THREE.Shape();
      
      // 调整V形绘制方式使其更加尖锐
      // 添加中间的辅助点使顶部更尖锐
      shape.moveTo(-size.width/2, -size.height/2);  // 左下
      shape.lineTo(-size.width/4, 0);               // 左中间点，增加尖锐度
      shape.lineTo(0, size.height/2);               // 顶部尖点
      shape.lineTo(size.width/4, 0);                // 右中间点，增加尖锐度
      shape.lineTo(size.width/2, -size.height/2);   // 右下
      
      // 内部轮廓也需要对应调整
      shape.lineTo(size.width/2 - size.thickness, -size.height/2);  // 右下内
      shape.lineTo(size.width/4 - size.thickness/2, 0);             // 右中间内点
      shape.lineTo(0, size.height/2 - size.thickness);              // 顶部内尖点
      shape.lineTo(-size.width/4 + size.thickness/2, 0);            // 左中间内点
      shape.lineTo(-size.width/2 + size.thickness, -size.height/2); // 左下内
      shape.lineTo(-size.width/2, -size.height/2);  // 闭合

      const geometry = new THREE.ShapeGeometry(shape);
      const material = new THREE.MeshBasicMaterial({
        color: color,
        transparent: true,
        opacity: 0.9,
        side: THREE.DoubleSide
      });

      const arrow = new THREE.Mesh(geometry, material);
      arrow.position.y = yOffset;
      arrow.position.z = -2;
      arrow.rotation.x = -Math.PI / 2; // 使箭头平躺

      return arrow;
    };

    // 创建外层蓝色V形
    const outerArrow = createVShape(0x4285f4, {
      width: 1.404,  // 1.08 * 1.3 = 1.404 (增加30%)
      height: 0.1548, // 0.1191 * 1.3 = 0.1548 (增加30%)
      thickness: 0.1755 // 0.135 * 1.3 = 0.1755 (增加30%)
    }, 0.001);

    // 创建内层白色V形
    const innerArrow = createVShape(0xffffff, {
      width: 1.053,  // 0.81 * 1.3 = 1.053 (增加30%)
      height: 0.1239, // 0.0953 * 1.3 = 0.1239 (增加30%)
      thickness: 0.1404 // 0.108 * 1.3 = 0.1404 (增加30%)
    }, 0.002);

    // 将两个箭头添加到组中
    const arrowPair = new THREE.Group();
    arrowPair.add(outerArrow);
    arrowPair.add(innerArrow);

    // 创建多个箭头对
    const arrowCount = 4;
    const arrowSpacing = 0.8775; // 0.675 * 1.3 = 0.8775 (增加30%)

    for (let i = 0; i < arrowCount; i++) {
      const clonedArrowPair = arrowPair.clone();
      clonedArrowPair.position.z = -i * arrowSpacing;
      arrowGroup.add(clonedArrowPair);
    }

    // 调整整个箭头组的位置，使其与小地图顶部完全贴合
    arrowGroup.position.y = -1.5; // 进一步下移使箭头与小地图顶部贴合
    arrowGroup.position.z = -1.0; // 调整前后距离，使箭头看起来更接近小地图
    
    // 保存箭头组引用
    this.navArrow = arrowGroup;
    scene.add(arrowGroup);
  },
  
  // 开始监听设备方向
  startDeviceOrientation: function() {
    // 如果已经在监听中，就不再重复启动
    if (this.deviceMotionListeningActive) {
      console.log('设备方向监听已经启动，不需要重复启动');
      return;
    }
    
    // 请求罗盘权限
    wx.startDeviceMotionListening({
      success: (res) => {
        console.log('开始设备方向监听成功');
        // 更新监听状态标志
        this.deviceMotionListeningActive = true;
        
        // 创建一个局部工具对象，包含需要的函数和状态引用
        const utils = {
          // 角度转弧度，直接在回调内使用而不依赖this
          degToRad: function(degrees) {
            return degrees * (Math.PI / 180);
          },
          // 保存对组件的引用
          context: this
        };
        
        // 监听设备方向变化
        const onMotionChange = function(res) {
          // 使用utils对象中保存的组件引用和工具函数
          const self = utils.context; 
          
          // 使用设备方向更新箭头方向
          if (self.navArrow && res.alpha !== undefined) {
            // 将设备方向转换为箭头旋转
            // alpha是设备绕z轴的旋转角度（指南针方向）
            const compassHeading = 360 - res.alpha;
            
            // 使用工具对象中的角度转弧度函数，不依赖this
            self.navArrow.rotation.y = utils.degToRad(compassHeading);
            
            // 保存方向用于地图标记
            self.lastDirection = compassHeading;
            
            // 计算与目标方向的差异并更新方向指示器
            if (self.data.navMode && self.targetDirection !== undefined) {
              // 计算当前方向与目标方向的角度差
              let angleDiff = self.targetDirection - compassHeading;
              
              // 标准化角度差到 -180 到 180 度之间
              while (angleDiff > 180) angleDiff -= 360;
              while (angleDiff < -180) angleDiff += 360;
              
              // 设置显示阈值（当方向差大于35度时显示指示器）
              const showThreshold = 35; // 提高阈值，减少轻微晃动引起的显示变化
              
              // 使用多阈值系统，提供更稳定的方向判断
              const correctThreshold = 25; // 认为方向基本正确的阈值（降低为25度）
              const smallDeviationThreshold = 60; // 小幅度偏离的阈值
              const largeDeviationThreshold = 100; // 大幅度偏离的阈值
              
              // 为防止抖动，使用不同的阈值进入和退出"方向正确"状态
              // 仅当角度差绝对值大于showThreshold才显示指示器
              // 仅当角度差绝对值小于correctThreshold才认为方向正确
              let shouldShowIndicator = false;
              
              // 如果当前未显示指示器，则使用进入阈值判断
              if (!self.data.showDirectionIndicator) {
                shouldShowIndicator = Math.abs(angleDiff) > showThreshold;
              } else {
                // 如果已经显示指示器，使用退出阈值判断
                shouldShowIndicator = Math.abs(angleDiff) > correctThreshold;
              }
              
              // 确定文字提示和箭头颜色
              let directionText = '方向正确';
              let arrowColor = '';
              
              // 根据角度差的大小调整文字提示和颜色，采用区间判断，避免频繁切换
              if (Math.abs(angleDiff) <= correctThreshold) {
                directionText = '方向正确';
                arrowColor = '#34a853'; // 绿色
                // 保持指示器可见，显示"方向正确"
                shouldShowIndicator = true;
              } else if (Math.abs(angleDiff) > largeDeviationThreshold) {
                // 角度差非常大，表示几乎相反方向
                directionText = angleDiff > 0 ? '请向左大幅转向' : '请向右大幅转向';
                arrowColor = '#ea4335'; // 红色
              } else if (Math.abs(angleDiff) > smallDeviationThreshold) {
                // 角度差较大，需要明显转向
                directionText = angleDiff > 0 ? '向左转' : '向右转';
                arrowColor = '#fbbc05'; // 黄色
              } else {
                // 小角度调整
                directionText = angleDiff > 0 ? '稍微向左转' : '稍微向右转';
                arrowColor = '#4285f4'; // 蓝色
              }
              
              // 仅当状态真正改变时才更新UI
              if (self.data.showDirectionIndicator !== shouldShowIndicator ||
                  Math.abs(self.data.directionAngle - angleDiff) > 15 ||  // 只有角度变化超过15度才更新
                  self.data.directionText !== directionText ||
                  self.data.arrowColor !== arrowColor) {
                
                // 计算平滑角度，减少指示箭头的抖动
                let smoothedAngle = angleDiff;
                if (self.lastReportedAngle !== undefined) {
                  // 平滑处理：70%当前值，30%新值
                  smoothedAngle = self.lastReportedAngle * 0.7 + angleDiff * 0.3;
                }
                self.lastReportedAngle = smoothedAngle;
                
                // 当角度小于正确阈值时，确保显示"方向正确"指示器
                if (Math.abs(angleDiff) <= correctThreshold) {
                  shouldShowIndicator = true;
                  directionText = '方向正确';
                  arrowColor = '#34a853'; // 绿色
                }
                
                // 更新UI数据
                self.setData({
                  showDirectionIndicator: shouldShowIndicator,
                  directionAngle: smoothedAngle,
                  directionText: directionText,
                  arrowColor: arrowColor
                });
                
                // 输出调试日志
                console.log(`方向指示状态: 显示=${shouldShowIndicator}, 角度=${smoothedAngle.toFixed(1)}°, 提示="${directionText}"`);
              }
            }
            
            // 导航更新与方向指示器更新分离，防止相互干扰
            // 每6次方向更新才触发一次导航更新，进一步降低导航更新频率
            if (!self.motionUpdateCount) {
              self.motionUpdateCount = 0;
            }
            
            self.motionUpdateCount = (self.motionUpdateCount + 1) % 6;
            
            // 只在计数为0时触发导航更新
            if (self.data.navMode && self.data.latitude && self.data.longitude && self.motionUpdateCount === 0) {
              self.updateNavigation(self.data.longitude, self.data.latitude);
            }
          }
        };
        
        // 监听设备方向变化，不需要绑定this
        wx.onDeviceMotionChange(onMotionChange);
      },
      fail: (err) => {
        console.error('开始设备方向监听失败：', err);
        this.deviceMotionListeningActive = false;  // 确保状态标志正确反映失败情况
      }
    });
  },
  
  // 停止设备方向监听
  stopDeviceOrientation: function() {
    // 先尝试取消事件监听，无论设备监听是否活跃
    try {
      wx.offDeviceMotionChange();
      console.log('已解除设备方向变化监听');
    } catch (e) {
      console.error('解除设备方向监听失败:', e);
    }
    
    // 如果设备方向监听未启动，则不尝试停止
    if (!this.deviceMotionListeningActive) {
      console.log('设备方向监听未启动，无需停止');
      // 确保方向引用被清除
      this.lastDirection = undefined;
      return;
    }
    
    // 尝试停止设备方向监听
    try {
      wx.stopDeviceMotionListening({
        success: (res) => {
          console.log('停止设备方向监听成功');
          this.deviceMotionListeningActive = false;
        },
        fail: (err) => {
          console.error('停止设备方向监听失败:', err);
          // 尽管API调用失败，但我们仍将状态重置为未监听
          this.deviceMotionListeningActive = false;
        },
        complete: () => {
          // 清除方向引用
          this.lastDirection = undefined;
        }
      });
    } catch (error) {
      console.error('调用停止设备方向监听API失败:', error);
      // 确保在出错时也清除引用和状态
      this.lastDirection = undefined;
      this.deviceMotionListeningActive = false;
    }
  },
  
  // 更新箭头方向
  updateNavArrowDirection: function(currentStep) {
    if (!currentStep || !currentStep.polyline || currentStep.polyline.length < 1) {
      return;
    }
    
    // 获取当前位置和下一个导航点
    const currentPos = {
      lat: this.data.latitude,
      lng: this.data.longitude
    };
    
    // 找到最近的点和下一个需要到达的点
    let minDist = Infinity;
    let nearestPoint = null;
    let nextPoint = null;
    let nearestIndex = -1;
    
    currentStep.polyline.forEach((point, index) => {
      const dist = this.calculateDistance(
        currentPos.lat, currentPos.lng,
        point.latitude, point.longitude
      );
      
      if (dist < minDist) {
        minDist = dist;
        nearestPoint = point;
        nearestIndex = index;
      }
    });
    
    // 找到下一个导航点（如果当前点不是终点）
    const totalPoints = currentStep.polyline.length;
    if (nearestIndex >= 0 && nearestIndex < totalPoints - 1) {
      // 使用当前点后1-3个点之间的点作为目标点
      // 这样目标不会太近，导航更平滑
      const nextIndex = Math.min(nearestIndex + 3, totalPoints - 1);
      nextPoint = currentStep.polyline[nextIndex];
    } else if (totalPoints > 0) {
      // 如果当前最近的点就是终点，则继续指向终点
      nextPoint = currentStep.polyline[totalPoints - 1];
    }
    
    // 如果找到了导航目标点，计算指向该点的方向角度
    if (nextPoint) {
      // 计算指向下一个点的方向角度
      const dx = nextPoint.longitude - currentPos.lng;
      const dy = nextPoint.latitude - currentPos.lat;
      
      // 计算方位角（以北为0度，顺时针增加）
      let bearing = Math.atan2(dx, dy) * 180 / Math.PI;
      if (bearing < 0) {
        bearing += 360;
      }
      
      // 检查方向角度是否有显著变化
      const directionChanged = this.targetDirection === undefined || 
                               Math.abs(bearing - this.targetDirection) > 15;
      
      // 只有当方向有显著变化或者是首次设置时，才更新目标方向
      if (directionChanged) {
        // 如果有前一个方向，进行平滑处理
        if (this.targetDirection !== undefined) {
          // 平滑目标方向变化：60%前值，40%新值
          this.targetDirection = this.targetDirection * 0.6 + bearing * 0.4;
        } else {
          // 首次设置，直接使用计算值
          this.targetDirection = bearing;
        }
        
        console.log('目标方向已更新:', this.targetDirection.toFixed(2));
      }
      
      // 调整AR箭头的颜色
      if (this.navArrow && this.navArrow.children) {
        // 根据到下一个点的距离设置颜色
        let arrowColor;
        
        if (minDist < 10) {
          // 非常接近，显示绿色
          arrowColor = 0x34a853; // 绿色
        } else if (minDist < 50) {
          // 50米内，显示蓝色
          arrowColor = 0x4285f4; // 蓝色
        } else if (minDist < 200) {
          // 200米内，显示黄色
          arrowColor = 0xfbbc05; // 黄色
        } else {
          // 距离较远，显示红色
          arrowColor = 0xea4335; // 红色
        }
        
        // 更新AR箭头颜色
        this.navArrow.children.forEach(arrowPair => {
          if (arrowPair.children && arrowPair.children.length >= 2) {
            // 外层箭头使用主题色
            if (arrowPair.children[0] && arrowPair.children[0].material) {
              arrowPair.children[0].material.color.setHex(arrowColor);
            }
            
            // 内层箭头保持白色
            if (arrowPair.children[1] && arrowPair.children[1].material) {
              arrowPair.children[1].material.color.setHex(0xffffff);
            }
          }
        });
      }
    }
  },
  
  // 页面隐藏时清理资源
  onHide: function() {
    // 如果当前在导航模式，保存状态并暂停相关功能
    if (this.data.navMode) {
      console.log('页面隐藏，暂停导航相关功能');
      
      // 停止位置更新
      this.stopLocationUpdate();
      
      // 停止设备方向监听
      this.stopDeviceOrientation();
      
      // 恢复原始的setData方法
      if (this.oldSetData) {
        this.setData = this.oldSetData;
        this.oldSetData = null;
      }
    }
  },
  
  // 在销毁时清理资源
  onUnload: function() {
    console.log('页面卸载，清理所有资源');
    
    // 先将所有模式标志设为false，确保不会有未处理的状态
    this.setData({
      navMode: false,
      arMode: false,
      showMap: false,
      showCamera: false
    });
    
    // 恢复原始的setData方法
    if (this.oldSetData) {
      this.setData = this.oldSetData;
      this.oldSetData = null;
    }
    
    // 停止位置更新
    this.stopLocationUpdate();
    
    // 停止设备方向监听
    this.stopDeviceOrientation();
    
    // 取消所有可能的监听
    try {
      wx.offLocationChange();
      wx.offDeviceMotionChange();
    } catch (e) {
      console.error('取消监听失败:', e);
    }
    
    // 停止所有动画循环
    if (this.canvas && this.animationId) {
      try {
        this.canvas.cancelAnimationFrame(this.animationId);
      } catch (e) {
        // 忽略错误
      }
    }
    
    // 清理THREE.js资源
    this.cleanupThreeJS();
    
    console.log('页面资源清理完成');
  },
  
  // 清理THREE.js资源
  cleanupThreeJS: function() {
    // 清理主场景资源
    if (this.renderer) {
      try {
        this.renderer.dispose();
        this.renderer = null;
      } catch (e) {
        // 忽略错误
      }
    }
    
    if (this.cube && this.cube.geometry) {
      try {
        this.cube.geometry.dispose();
      } catch (e) {
        // 忽略错误
      }
    }
    
    if (this.cube && this.cube.material) {
      try {
        this.cube.material.dispose();
      } catch (e) {
        // 忽略错误
      }
    }
    
    this.scene = null;
    this.camera = null;
    this.cube = null;
    
    // 清理AR场景资源
    if (this.navRenderer) {
      try {
        this.navRenderer.dispose();
        this.navRenderer = null;
      } catch (e) {
        // 忽略错误
      }
    }
    
    this.navScene = null;
    this.navCamera = null;
    this.navArrow = null;
    
    // 清理THREE对象
    this.THREE = null;
    this.navTHREE = null;
  }
})
